#ifndef NETWORK_H
#define NETWORK_H

#include <string.h> // memset
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <queue>
#include <pthread.h>

#include "../utils/data_types.h"
#include "../Event/Event.h"
#include "../utils/Mutex/Mutex.h"
#include "../utils/ApplicationLog/ApplicationLog.h"

#include "NetworkMessage.h"

class Network
{
    public:
        
        // :THREADED:
        ~Network();
        
        // :THREADED:
        bool Send(int target_sockfd, NetworkMessage* msg);
        
        Event<int,NetworkMessage*>& OnNewMessage();
        
    protected:
        
        // :THREADED:
        int _sock_fd;
        Mutex _sock_fd_mutex;
        
        // :THREADED: but used sequentialy
        fd_set ready;
        int maxsock;
        
        bool Initialize();
        
        // :THREADED:
        void HandleNewData(int target_sockfd);
        void QuitMainLoop();
        
        // :THREADED:
        virtual void PrepareSet() = 0;
        virtual void HandleActiveSockets() = 0;
        virtual void LostConnectionHandler(int target_sockfd) = 0;
        
    private:
        
        pthread_t thread;
        
        // :THREADED:
        bool _quit_update_loop;
        Mutex _quit_update_loop_mutex;
        
        // :TODO: @Author: tfischer
        // algunos eventos deberian ser thread safe !!
        Event<int,NetworkMessage*> _new_message_event;
        
        // Aux functions
        
        // :THREADED:
        void Update();
        
        // :THREADED:
        void MainLoop();
        
        // :THREADED:
        static void* Wrapper(void* arg);
};

#endif
